import {HeartPopMessage_200} from '@/proto/message/impl/system/HeartPopMessage_200';
import {SessionBuildResponse_100} from '@/proto/message/impl/system/SessionBuildResponse_100';
import {UserSendMessage_1004} from '@/proto/message/impl/channel/UserSendMessage_1004';
import {UserReceiveMessage_1005} from '@/proto/message/impl/channel/UserReceiveMessage_1005';
import {UserJoinChannelNotice_1006} from '@/proto/message/impl/channel/UserReceiveMessage_1007';
import {UserOnlineStatusNotice_1007} from '@/proto/message/impl/channel/UserReceiveMessage_1006';
import IMessage from '@/proto/message/IMessage';
import MessageObject from "@/model/message/MessageObject";

// 消息处理中心
export default class MessageHandlerManager {
  private msgId2Obj: Map<number, any> = new Map<number, any>();

  private static _instance = new MessageHandlerManager();

  /**
   * 消息长度 2 * 8 = 16位
   * @private
   */
  private static Message_length = 2;

  constructor() {
    this.loadAllMsgInfo();
  }

  public static getInstance(): MessageHandlerManager {
    return this._instance;
  }

  public static getMessageInfoByMsgId(MsgId: number): any {
    return MessageHandlerManager.getInstance().msgId2Obj.get(MsgId);
  }

  /**
   * 将整数转换为二进制
   * @param value
   * @constructor
   */
  public static ToBinary(value: number): any {
    let num = value;
    const resArry = [];
    const xresArry = [];
    let i = 0;
    // 除2取余
    for (; num > 0;) {
      resArry.push(num % 2);
      num = parseInt(String(num / 2));
      i++;
    }
    let j = 0;
    // 倒序排列
    for (j = i - 1; j >= 0; j--) {
      xresArry.push(resArry[j]);
    }
    const finalArr = [];
    let pos = 0;
    for (; pos < 16 - xresArry.length; pos++) {
      finalArr[pos] = 0;
    }
    for (let k = 0; k < xresArry.length; k++) {
      finalArr[pos] = xresArry[k];
      pos++;
    }
    let first = parseInt(finalArr.slice(0, 8).join('').replace(/,/g, ""),2);
    let second = parseInt(finalArr.slice(8, 16).join('').replace(/,/g, ""),2);

    return [first, second];
  }

  /**
   * 对消息进行解码
   */
  public static decode(binaryData: ArrayBuffer): MessageObject {
    console.log('接收到消息，原始二进制数据3', binaryData)
    //转为Uint8Array
    let u8a = new Uint8Array(binaryData);
    let binaryMsgId = '';
    for (let i = 0; i < MessageHandlerManager.Message_length; i++) {
      binaryMsgId += u8a[i].toString(2);
    }
    const msgId: number = parseInt(binaryMsgId, 2);
    const protobufData = [];
    for (let i = MessageHandlerManager.Message_length; i < u8a.length; i++) {
      protobufData.push(u8a[i]);
    }
    const message = MessageHandlerManager.getMessageInfoByMsgId(msgId);
    return {decodeMessage: message.decode(protobufData), msgId};
  }

  /**
   * 对消息编码
   * @param obj protobuf生成的接口
   * @param msgId
   */
  public static encode(obj: any, msgId: number): Uint8Array {
    const message = MessageHandlerManager.getMessageInfoByMsgId(msgId);
    const msgBinary = message.encode(obj);
    const msgIdBinary = MessageHandlerManager.ToBinary(msgId);
    const dataList = [];
    for (let i = 0; i < msgIdBinary.length; i++) {
      dataList.push(msgIdBinary[i]);
    }
    let pos = dataList.length;
    for (let i = 0; i < msgBinary.length; i++) {
      dataList[pos] = msgBinary[i];
      pos++;
    }
    return Uint8Array.from(dataList);
  }

  add(obj: IMessage,msgId: number) {
    // 获取类名，获取消息号
    this.msgId2Obj.set(msgId, obj);
    console.log('消息号', msgId);
  }

  loadAllMsgInfo() {
    this.add(new SessionBuildResponse_100(), 100);
    this.add(new HeartPopMessage_200(), 200);
    this.add(new UserSendMessage_1004(), 1004);
    this.add(new UserReceiveMessage_1005(), 1005);
    this.add(new UserJoinChannelNotice_1006(), 1006);
    this.add(new UserOnlineStatusNotice_1007(), 1007);
  }
}
